<template>
  <div class="publish-container">
    <!-- 卡片模式 -->
    <el-card>
      <!-- 卡片上部 -->
      <div slot="header">
        <!-- 面包屑导航 -->
        <el-breadcrumb>
          <el-breadcrumb-item to="/">首页</el-breadcrumb-item>
          <el-breadcrumb-item>发布文章</el-breadcrumb-item>
        </el-breadcrumb>
      </div>

      <!-- 发布文章_表单 -->
      <el-form ref="form" :model="article" :rules="rules" label-width="80px">
        <el-form-item label="标题" prop="title">
          <el-input v-model="article.title"></el-input>
        </el-form-item>
        <el-form-item label="内容" prop="content">
          <!-- <el-input type="textarea" v-model="article.content"></el-input> -->
          <quill-editor
          v-model="article.content"
          :options="editorOption"
          ></quill-editor>
        </el-form-item>
        <!-- 因为切换封面图片类型时, images数组也要清空 -->
        <el-form-item label="封面">
          <el-radio-group
          v-model="article.cover.type"
          @change="typeChange"
          >
            <el-radio :label="1">单图</el-radio>
            <el-radio :label="3">三图</el-radio>
            <el-radio :label="0">无图</el-radio>
            <el-radio :label="-1">自动</el-radio>
          </el-radio-group>
        </el-form-item>
        <el-form-item prop="cover">
          <!-- v-if不符合条件, 里面的标签不会挂载执行(所以也就避免了v-for对-1循环的报错)
            口诀:v-if和v-show的特点就知道什么时候该用哪个了
           -->
          <el-row :gutter="20" v-if="article.cover.type !== -1">
            <el-col :span="5" v-for="(num, index) in article.cover.type" :key="num">
              <!-- 自定义组件使用v-model指令(原理把右侧的值, 赋予给当前组件的value属性)
              传入数据 (内部必须叫value的props属性接收) -->
              <MyCover @coverimg="coverImgFn" :index="index" v-model="article.cover.images[index]"/>
            </el-col>
          </el-row>
        </el-form-item>
        <el-form-item label="频道" prop="channel_id">
          <el-select v-model="article.channel_id" placeholder="请选择频道">
            <el-option
              v-for="obj in channelArr"
              :key="obj.id"
              :label="obj.name"
              :value="obj.id"
            ></el-option>
          </el-select>
        </el-form-item>

        <el-form-item>
          <!-- el-button内部自己实现了click事件 (内部this.$emit("click")) -->
          <!-- 下拉菜单内部没有实现click事件 -->
          <el-button type="primary" @click="createFn(false)">发表</el-button>
          <el-button @click="createFn(true)">存入草稿</el-button>
        </el-form-item>
      </el-form>
    </el-card>
  </div>
</template>

<script>
// 接口
import { channelListAPI, articleAddAPI, articleByIdAPI, articleUpdateAPI } from '@/api' // 如果是文件夹默认找index.js(可以省略)

// 富文本插件 (除了JS文件, 直接引入无需变量接受)
import 'quill/dist/quill.core.css'
import 'quill/dist/quill.snow.css'
import 'quill/dist/quill.bubble.css'
import { quillEditor } from 'vue-quill-editor'

// 规则
import { articleAddRules } from '@/verify'

// 引入封面组件MyCover
import MyCover from '@/components/MyCover'

export default {
  name: 'articleAdd',
  data () {
    return {
      article: {
        title: '',
        content: '',
        cover: {
          type: 0,
          images: []
        },
        channel_id: ''
      },
      channelArr: [], // 装请求回来的频道数组
      editorOption: {
        modules: {
          toolbar: [
            ['bold', 'italic', 'underline', 'strike'], // 加粗, 斜体, 下划线, 删除线
            ['blockquote', 'code-block'], // 双引号和代码
            [{ header: 1 }, { header: 2 }], // h几字体图标
            [{ list: 'ordered' }, { list: 'bullet' }], // 有序列表, 无序列表
            [{ indent: '-1' }, { indent: '+1' }], // 缩进-1, 缩进+1 按钮
            ['image'] // 图片插件
          ]
        }
      },
      rules: articleAddRules,
      artId: -1 // 正在编辑的文章id(如果为-1证明现在是发布状态)
    }
  },
  methods: {
    createFn (bool) {
      // if (this.article.cover.type !== this.article.cover.images.length) {
      //   this.$message.error('图片数量对不上')
      //   return
      // }
      this.$refs.form.validate(async valid => { // 点击发布的时候, 还需要手动调用一下校验规则
        if (valid === false) return

        if (this.artId !== -1) { // 更新文章, 调用更新的接口
          const [err] = await articleUpdateAPI(this.artId, { draft: bool }, this.article)
          if (err) return
          // 成功更新后, 跳回到文章列表页面
          this.$message({
            message: '更新文章成功了',
            type: 'success'
          })
          this.$router.replace('/layout/articleList')
        } else {
          const [err] = await articleAddAPI({ draft: bool }, this.article)
          if (err) return
          this.$message({
            message: '发布文章成功',
            type: 'success'
          })
        }

        // 组件内 data函数变量, 绑定到$data上
        // this.$options 获取的当前组件的export default后对象
        // this.$options.data() 调data函数执行, 原地得到return后的对象(带初值)

        // console.log(this.$options.data()) // 初始data对象
        // console.log(this.$data) // 绑定数据后的对象
        // console.log(this.$data.article) // 值
        // console.log(this.article) // 和上面相等, $data可以省略的

        // 总结: 原始初始值 this.$options.data()
        // 现在最新状态的值 this.$data

        // 口诀: 设置回初始值
        Object.assign(this.article, this.$options.data().article)

        // 为啥不用=, 要用Object.assign()
        // 用=可能造成对象的互相引用
        // Object.assign()会把后面的key和value直接"拷贝"给前面对象里的key和value上
        // article受影响, 页面也受影响(效果: 输入框的值又变成了最开始的空值)
      })
    },
    typeChange () { // 封面类型改变事件
      if (this.article.cover.type === 0 || this.article.cover.type === -1) {
        // 用户选择了封面为无图/自动, 我们要把cover下的images图片数组清空
        this.article.cover.images = []
      } else if (this.article.cover.type === 1) { // 如果单图, 数组只保存第一个
        this.article.cover.images = this.article.cover.images.slice(0, 1)
      }
    },
    coverImgFn (imgUrl, index) { // 内部传出的封面图片地址
    // 问题1: 不用push()原因, 点击多次会超出3张
    // 解决: 3个组件把自己的下标传过来, 放到数组里面 (3组件 - 数组3位置 映射关系ok了)

      // 问题2: 选中了又取消了, 判断
      if (imgUrl === false) { // 取消-删除
        this.article.cover.images[index] = undefined // 组件序号-页面-数组数据(对上, 所以不能删除)
      } else { // 选择, 重新选择 - 替换数组里的元素
        this.article.cover.images[index] = imgUrl
      }
    }
  },
  async created () {
    const [err, res] = await channelListAPI() // 获取频道列表
    if (err) return
    this.channelArr = res.data.data.channels

    // 从当前url上提取id的值(文章id), 如果有就代表现在是编辑状态 / 如果无就是发布新文章状态
    if (this.$route.query.id) { // 如果有id再执行获取
      this.artId = this.$route.query.id
      const [err, artRes] = await articleByIdAPI(this.artId)
      if (err) return
      // 之前我们的参数名已经和后台的参数名对上了, 这里直接把数据对象覆盖到article就影响到了页面表单值绑定的变量
      // 默认数据显示到页面上
      // Object.keys() 提取对象里的key的集合(会把所有的key放到数组返回在原地)
      if (Object.keys(artRes.data.data).length === 0) { // 防止用户调皮传一个假的id(url上)
        this.$message({
          message: '查无此文章-请确认id',
          type: 'warning',
          onClose: () => { // this要指向外层this的值(vue对象才能调用$router)
            this.$router.replace('/layout/articleList')
          }
        })
      } else {
        this.article = artRes.data.data
      }
    }
  },
  components: {
    quillEditor,
    // mycover: MyCover
    MyCover
  }
}
</script>

<style lang="less" scoped >
// scoped (webpack在提取这里代码的时候, 只会把这个类名作用域当前组件的class上)
// 子组件quill-editor里的类名不会被这里影响和修改

// 在父组件中去设置子组件的样式，加上/deep/ 实现穿透功能
.publish-container /deep/ .ql-editor {
  height: 300px;
}
.publish-container /deep/ .ql-toolbar.ql-snow {
  padding: 0 8px;
}
</style>
